package com.example.focusimageview.util;


import android.annotation.SuppressLint;
import android.os.Build;
import android.util.Base64;

import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Provider;
import java.security.SecureRandom;
import java.util.Collection;
import java.util.Map;
import java.util.Objects;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

/**
 * Created by zhicheng.zhao on 2020/7/17.
 */
public class SignUtil {
    private static final String AES = "AES";
    private static final String SP = "SHA1PRNG";
    private static final String CHARACTER = "utf-8";


    /**
     * 排序参数
     * @param keyMap
     * @return
     */

    /**
     * 对原字符串进行加密
     * @param content 原字符串
     * @return
     */
    @SuppressLint({"DeletedProvider", "GetInstance"})
    public static String encode(String content, String key) {
        try {
            SecretKeySpec secretKeySpec;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
               secretKeySpec = deriveKeyInsecurely(key);
            } else {
                secretKeySpec = fixSmallVersion(key);
            }
            Cipher cipher = Cipher.getInstance("AES/ECB/ZeroBytePadding");
            byte[] byteContent = content.getBytes(CHARACTER);
            cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
            byte[] result = cipher.doFinal(byteContent);
            // 对sign进行编码，防止加号变为空格
            return parseByte2HexStr(result);
        } catch (NoSuchAlgorithmException | BadPaddingException | IllegalBlockSizeException | InvalidKeyException | NoSuchPaddingException | NoSuchProviderException | UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 对加密的字符串解密
     * @param content 加密的字符串
     * @return
     */
    public static String decode(String content, String key) {
        try {
            // 对sign进行解码(如后端自动url解码，不需要再进行url解码)
            byte[] decryptFrom = parseHexStr2Byte(content);
            SecretKeySpec secretKeySpec;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
                secretKeySpec = deriveKeyInsecurely(key);
            } else {
                secretKeySpec = fixSmallVersion(key);
            }
            Cipher cipher = Cipher.getInstance("AES/ECB/ZeroBytePadding");// 创建密码器
            cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);// 初始化
            byte[] result = cipher.doFinal(decryptFrom);
            return new String(result); // 加密
        } catch (NoSuchAlgorithmException | BadPaddingException | IllegalBlockSizeException |
                InvalidKeyException | NoSuchPaddingException |
                NoSuchProviderException e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 将二进制转换成16进制
     * @param buf
     * @return
     */
    @SuppressLint("NewApi")
    private static String parseByte2HexStr(byte buf[]) {
        return new String(Base64.encodeToString(buf,32));
    }

    /**
     * 将16进制转换为二进制
     * @param hexStr
     * @return
     */
    @SuppressLint("NewApi")
    private static byte[] parseHexStr2Byte(String hexStr) {
        return Base64.decode(hexStr,32);
    }


    public static boolean isEmpty(Object obj) {
        if (obj == null) {
            return true;
        } else if (obj instanceof String && Objects.equals(String.valueOf(obj).trim(), "")) {
            return true;
        } else if (obj instanceof String && Objects.equals(String.valueOf(obj).trim(), "null")) {
            return true;
        } else if (obj instanceof Boolean && !((Boolean) obj)) {
            return true;
        } else if (obj instanceof Collection && ((Collection) obj).isEmpty()) {
            return true;
        } else if (obj instanceof Map && ((Map) obj).isEmpty()) {
            return true;
        } else if (obj instanceof Object[] && ((Object[]) obj).length == 0) {
            return true;
        }
        return false;
    }

    private static SecretKeySpec deriveKeyInsecurely(String password) {
        byte[] passwordBytes = new byte[0];
        passwordBytes = password.getBytes(StandardCharsets.UTF_8);
        return new SecretKeySpec(InsecureSHA1PRNGKeyDerivator.deriveInsecureKey(passwordBytes, 32), "AES/ECB/ZeroBytePadding");
    }

    @SuppressLint("DeletedProvider")
    private static SecretKeySpec fixSmallVersion(String password) throws NoSuchAlgorithmException, NoSuchProviderException {
        KeyGenerator kgt = KeyGenerator.getInstance("AES");
        SecretKey secretKey = kgt.generateKey();
        SecureRandom secureRandom;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            secureRandom = SecureRandom.getInstance(SP, new CryptoProvider());
        } else {
            secureRandom = SecureRandom.getInstance(SP, "Crypto");
        }
        secureRandom.setSeed(password.getBytes());
        kgt.init(128, secureRandom);

        byte[] enCodeFormat = secretKey.getEncoded();
        return new SecretKeySpec(enCodeFormat, "AES/ECB/ZeroBytePadding");
    }


    private static final class CryptoProvider extends Provider {
        CryptoProvider() {
            super("Crypto", 1.0, "HARMONY (SHA1 digest; SecureRandom; SHA1withDSA signature)");
            put("SecureRandom.SHA1PRNG", "org.apache.harmony.security.provider.crypto.SHA1PRNG_SecureRandomImpl");
            put("SecureRandom.SHA1PRNG ImplementedIn", "Software");
        }
    }
}
